package com.polytech.diploma.OracleStatStep;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

import org.pentaho.di.core.database.Database;
import org.pentaho.di.core.exception.KettleValueException;
import org.pentaho.di.core.row.RowDataUtil;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.ValueMetaInterface;
import org.pentaho.di.trans.step.BaseStepData;
import org.pentaho.di.trans.step.BaseStepMeta;
import org.pentaho.di.trans.step.StepDataInterface;

import com.polytech.diploma.OracleStat.OracleQueryProcessor;
import com.polytech.diploma.OracleStat.SQLStatData;
import com.polytech.diploma.StatAccumulator.StatPercentage;

public class OracleStatStepData extends BaseStepData implements StepDataInterface {
	
	public RowMetaInterface outputRowMeta;
	public Object[]         outputRowData;
	
	private OracleQueryProcessor queryProcessor = null;
	
	public OracleStatStepData() {
		super();
	}
	
	public void init(BaseStepMeta meta, Database DBConnection) throws RuntimeException
	{      
		StatPercentage statPercentage = new StatPercentage()
											.setMaxCost(Double.parseDouble(((OracleStatStepMeta)meta).getCostPercent())/100)
											.setMaxMemory(Double.parseDouble(((OracleStatStepMeta)meta).getMemoryPercent())/100)
											.setMaxDuration(Double.parseDouble(((OracleStatStepMeta)meta).getDurationPercent())/100)
											.setMaxIO(Double.parseDouble(((OracleStatStepMeta)meta).getIoPercent())/100)
											.setMaxMPRows(Double.parseDouble(((OracleStatStepMeta)meta).getRowsPercent())/100)
											.setTotalNum(Double.parseDouble(((OracleStatStepMeta)meta).getTotalNumber()))
											.setTotalNumPercents(Double.parseDouble(((OracleStatStepMeta)meta).getTotalPercentage())/100);
		
		queryProcessor = new OracleQueryProcessor(((OracleStatStepMeta)meta).getSchemaName(), DBConnection, statPercentage);
	}
	
	public Set<SQLStatData> getStatDataRows()
	{
		return queryProcessor.processQueries();
	}
	
	public Object[] writeStatDataRow(SQLStatData statData) throws KettleValueException
	{
		Object[] outputRowData = RowDataUtil.allocateRowData(outputRowMeta.size());
		
		outputRowData[0] = convert(outputRowMeta.getValueMeta(0), statData.getSqlText());
        outputRowData[1] = convert(outputRowMeta.getValueMeta(1), statData.getRuntimeMemory());
        outputRowData[2] = convert(outputRowMeta.getValueMeta(2), statData.getPersistentMemory());
        outputRowData[3] = convert(outputRowMeta.getValueMeta(3), statData.getDiskReads());
        outputRowData[4] = convert(outputRowMeta.getValueMeta(4), statData.getBufferGets()); 
        outputRowData[5] = convert(outputRowMeta.getValueMeta(5), statData.getUserIOWaitTime());
        outputRowData[6] = convert(outputRowMeta.getValueMeta(6), statData.getRowsProcessed());
        outputRowData[7] = convert(outputRowMeta.getValueMeta(7), statData.getOptimizerCost());
        outputRowData[8] = convert(outputRowMeta.getValueMeta(8), statData.getElapsedTime());     
        outputRowData[9] = convert(outputRowMeta.getValueMeta(9), statData.getFirstLoadTime());
        outputRowData[10] = convert(outputRowMeta.getValueMeta(10), statData.getCommandType().getCmdType());
        outputRowData[11] = convert(outputRowMeta.getValueMeta(11), statData.getReplaceMap().toString());
        
        /*
         * TODO: add update statistics
         */
		
		return outputRowData;
	}
	
	private Object convert(ValueMetaInterface valueMeta, Object value) throws KettleValueException {
        return valueMeta.convertData(valueMeta, value);    
    }
	
	public void addStatDataRow(Object[] columns)
	{
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd/HH:mm:ss");
		
		/*
		 * TODO: check cast from object to string by Object.toString()
		 */
		try {
			SQLStatData statData = new SQLStatData.SQLStatDataBuilder()
											.setSqlText(columns[0].toString())
											.setRuntimeMemory(Integer.parseInt(columns[1].toString()))
											.setPersistentMemory(Integer.parseInt(columns[2].toString()))										
											.setDiskReads(Integer.parseInt(columns[3].toString()))
											.setBufferGets(Integer.parseInt(columns[4].toString()))
											.setUserIOWaitTime(Integer.parseInt(columns[5].toString()))
											.setRowsProcessed(Integer.parseInt(columns[6].toString()))
											.setOptimizerCost(Integer.parseInt(columns[7].toString()))											
											.setElapsedTime(Integer.parseInt(columns[8].toString()))
											.setFirstLoadTime(sdf.parse(columns[9].toString()))
											.setCommandType(Integer.parseInt(columns[10].toString()))
											.setReplaceList(new HashMap<String, List<String>>())
											.build();
			queryProcessor.addQuery(statData);

		} catch (NumberFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
	}
	
	public void dispose()
	{
		
	}	
}
